﻿using System;
using System.Collections;
using System.IO;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using YArchitech.Revit;

namespace YArchitech.HCLoad.Parameters
{
	public class SpaceSharedParameters
	{
		public static string AnnotateParamName
		{
			get
			{
				return "HYAnnotateText";
			}
		}

		public static bool Binding(string sSharedParamFileName, UIApplication rvtUIApp)
		{
			if (!File.Exists(sSharedParamFileName))
			{
				return false;
			}
			Application application = rvtUIApp.Application;
			application.SharedParametersFilename = sSharedParamFileName;
			SpaceSharedParameters.AddSharedParameters(application.OpenSharedParameterFile(), rvtUIApp);
			return true;
		}

		public static void AddSharedParameters(DefinitionFile defFile, UIApplication rvtUIApp)
		{
			Application application = rvtUIApp.Application;
			Document document = rvtUIApp.ActiveUIDocument.Document;
			Transaction transaction = new Transaction(document, "YArchitech_HCLoad_AddSharedParameters");
			try
			{
				transaction.Start();
				CategorySet categorySet = application.Create.NewCategorySet();
				Category category = document.Settings.Categories.get_Item(SpaceSharedParameters.SpaceCat);
				categorySet.Insert(category);
				InstanceBinding instanceBinding = application.Create.NewInstanceBinding(categorySet);
				BindingMap parameterBindings = document.ParameterBindings;
				foreach (DefinitionGroup definitionGroup in defFile.Groups)
				{
					foreach (Definition definition in definitionGroup.Definitions)
					{
						if (SpaceSharedParameters.AlreadyAddedSharedParameter(document, definition, SpaceSharedParameters.SpaceCat))
						{
							parameterBindings.ReInsert(definition, instanceBinding, SpaceSharedParameters.paramCat);
						}
						else
						{
							parameterBindings.Insert(definition, instanceBinding, SpaceSharedParameters.paramCat);
						}
					}
				}
			}
			catch (Exception ex)
			{
				transaction.RollBack();
				ex.ToString();
			}
			finally
			{
				transaction.Commit();
			}
		}

		public static bool AddSpaceAnnotateParameter(UIApplication rvtUIApp)
		{
			Application application = rvtUIApp.Application;
			Document document = rvtUIApp.ActiveUIDocument.Document;
			Transaction transaction = new Transaction(document, "YArchitech_HCLoad_AddSpaceAnnotateParameter");
			try
			{
				transaction.Start();
				DefinitionGroups groups = application.OpenSharedParameterFile().Groups;
				DefinitionGroup definitionGroup = groups.get_Item("YArchitech Other");
				if (definitionGroup == null)
				{
					definitionGroup = groups.Create("YArchitech Other");
				}
				if (definitionGroup.Definitions.get_Item("HYAnnotateText") == null)
				{
                    Definition definition = UnifiedModified.GetDefinition(definitionGroup, "HYAnnotateText", (ParameterType)2, false, true);
					CategorySet categorySet = application.Create.NewCategorySet();
					Category category = document.Settings.Categories.get_Item(SpaceSharedParameters.SpaceCat);
					categorySet.Insert(category);
					InstanceBinding instanceBinding = application.Create.NewInstanceBinding(categorySet);
					document.ParameterBindings.Insert(definition, instanceBinding);
				}
				transaction.Commit();
			}
			catch (Exception ex)
			{
				ex.ToString();
				return false;
			}
			return true;
		}

		private static bool AlreadyAddedSharedParameter(Document doc, string paraName, BuiltInCategory boundCategory)
		{
			try
			{
				DefinitionBindingMapIterator definitionBindingMapIterator = doc.ParameterBindings.ForwardIterator();
				while (definitionBindingMapIterator.MoveNext())
				{
					if (definitionBindingMapIterator.Key.Name.Equals(paraName))
					{
						IEnumerator enumerator = (definitionBindingMapIterator.Current as ElementBinding).Categories.GetEnumerator();
						{
							while (enumerator.MoveNext())
							{
								if (((Category)enumerator.Current).Id.IntegerValue.Equals(boundCategory))
								{
									return true;
								}
							}
						}
					}
				}
			}
			catch (Exception)
			{
				return false;
			}
			return false;
		}

		public static bool AlreadyAddedSharedParameter(Document doc, Definition def, BuiltInCategory boundCategory)
		{
			ExternalDefinition externalDefinition = def as ExternalDefinition;
			if (externalDefinition == null)
			{
				return SpaceSharedParameters.AlreadyAddedSharedParameter(doc, def.Name, boundCategory);
			}
			try
			{
				DefinitionBindingMapIterator definitionBindingMapIterator = doc.ParameterBindings.ForwardIterator();
				while (definitionBindingMapIterator.MoveNext())
				{
					ExternalDefinition externalDefinition2 = definitionBindingMapIterator.Key as ExternalDefinition;
					if (externalDefinition2 != null && externalDefinition2.GUID.Equals(externalDefinition.GUID))
					{
						return true;
					}
				}
			}
			catch (Exception)
			{
				return false;
			}
			return false;
		}

		public static bool SetParaNullId(Parameter parameter)
		{
			ElementId elementId = new ElementId(-1);
			if (!parameter.IsReadOnly)
			{
				parameter.Set(elementId);
				return true;
			}
			return false;
		}

		public static bool HasLoadParam(Document doc)
		{
			return SpaceSharedParameters.AlreadyAddedSharedParameter(doc, "HYAnnotateText", SpaceSharedParameters.SpaceCat);
		}

		private const string m_sAnnotateParamName = "HYAnnotateText";

		private const string m_sAnnotateParamGuid = "30c1c8cb-21b8-4016-9d6b-f1321061b195";

		private const string m_sOtherParamGroupName = "YArchitech Other";

        private static BuiltInCategory SpaceCat = (BuiltInCategory)(-2003600);

        private static BuiltInParameterGroup paramCat = (BuiltInParameterGroup)(-5000129);
	}
}
